/*
 * @Description 
 * @Autor lzhiqiang
 * @Date 2023-03-21 17:30:08
 * @LastEditors lzhiqiang
 * @LastEditTime 2023-04-04 09:55:16
 */
#include "http_server.h"
#include "log.h"

namespace johnsonli
{
namespace http
{
    static johnsonli::Logger::ptr g_logger = LOG_NAME("system");

    HttpServer::HttpServer(bool keepalive
               ,const std::string& servername
               ,johnsonli::IOManager* worker
               ,johnsonli::IOManager* io_worker
               ,johnsonli::IOManager* accept_worker)
        :TcpServer(servername, worker, io_worker, accept_worker)
        ,m_isKeepalive(keepalive) 
    {
        m_dispatch.reset(new ServletDispatch(servername));
    }

    void HttpServer::handleClient(Socket::ptr client) 
    {
//        LOG_DEBUG(g_logger) << "handleClient " << *client;
        HttpSession::ptr session(new HttpSession(client));
        do
        {
 //           LOG_INFO(g_logger) << "client: " <<*client;
            
            auto req = session->recvRequest();
           // LOG_INFO(g_logger) << "req: " <<*req;
            if(!req) 
            {
                LOG_DEBUG(g_logger) << "recv http request fail, errno="
                    << errno << " errstr=" << strerror(errno)
                    << " cliet:" << *client << " keep_alive=" << m_isKeepalive;
                break;
            }
            
            //LOG_DEBUG(g_logger) << "req->isClose(): " << req->isClose();
            HttpResponse::ptr rsp(new HttpResponse(req->getVersion()
                                ,req->isClose() || !m_isKeepalive));

            // rsp->setBody("hello world");
            
            // LOG_INFO(g_logger) << "request:" << std::endl
            //     << *req;

            // LOG_INFO(g_logger) << "response:" << std::endl
            //     << *rsp;

            //servlet dispatch负责处理对应的请求

            // 处理业务逻辑的iomanager
            // m_dispatch->handle(request, response, session);
            m_worker->schedule(std::bind(&HttpServer::doWorker, shared_from_this(), req, rsp, session));            

            // session->sendResponse(rsp); 
            // 处理io的 iomanager
            m_ioWorker->schedule(std::bind(&HttpServer::doSend, shared_from_this(), session, rsp));   

            if(!m_isKeepalive || req->isClose()) {
                // std::cout << "m_isKeepalive " << m_isKeepalive << std::endl;
                // std::cout << "req->isClose() " << req->isClose() << std::endl;
                break;
            }

        }while(m_isKeepalive);
        session->close();
    }

    void HttpServer::doWorker(johnsonli::http::HttpRequest::ptr request
               , johnsonli::http::HttpResponse::ptr response
               , johnsonli::http::HttpSession::ptr session) {
            m_dispatch->handle(request, response, session);
    }

    void HttpServer::doSend(johnsonli::http::HttpSession::ptr session, johnsonli::http::HttpResponse::ptr response) {
            session->sendResponse(response); 
    }


    void HttpServer::setName(const std::string& v) 
    {
        TcpServer::setName(v);
        m_dispatch->setDefault(std::make_shared<NotFoundServlet>(v));
    }
}
}